package com.wyh.service.serviceImpl.gfiveImpl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyh.domain.dto.gfive.PermissionNode;
import com.wyh.domain.po.gfive.Permissions;
import com.wyh.service.gfive.PermissionsService;
import com.wyh.mapper.gfivemapper.PermissionsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 32276
 * @description 针对表【permissions(权限表)】的数据库操作Service实现
 * @createDate 2024-05-20 09:55:57
 */
@Service
public class PermissionsServiceImpl extends ServiceImpl<PermissionsMapper, Permissions>
        implements PermissionsService {

    @Autowired
    private PermissionsMapper permissionsMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public Set<String> selectPermsByRoleId(Integer id) {
        return permissionsMapper.selectPermsByRoleId(id);
    }

    @Override
    public List<PermissionNode> getPermissionTree() {
        List<PermissionNode> PermissionRootNodes = getPermissionTreeFromRedis();
        if (PermissionRootNodes != null && !PermissionRootNodes.isEmpty()) {
            return PermissionRootNodes;
        }
        // 首先获取所有权限数据
        List<Permissions> permissions = permissionsMapper.selectList(null);

        // 将权限数据转换为 PermissionNode 对象
        List<PermissionNode> nodes = permissions.stream()
                .map(p -> new PermissionNode(p.getId(), p.getName(), p.getAuthority(), p.getResource(),
                        p.getState(), p.getMenu(), p.getExpression(), p.getFatherid()))
                .collect(Collectors.toList());

        // 构建树结构
        List<PermissionNode> rootNodes = new ArrayList<>();
        for (PermissionNode node : nodes) {
            if (node.getFatherid() == 0) {
                rootNodes.add(node);
            } else {
                PermissionNode parent = findParentNode(nodes, node.getFatherid());
                if (parent != null) {
                    parent.getChildren().add(node);
                }
            }
        }
        // 将树结构保存到Redis
        savePermissionTreeToRedis(rootNodes);
        return rootNodes;
    }

    private PermissionNode findParentNode(List<PermissionNode> nodes, int parentId) {
        for (PermissionNode node : nodes) {
            if (node.getId() == parentId) {
                return node;
            }
        }
        return null;
    }

    private List<PermissionNode> getPermissionTreeFromRedis() {
        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("permission:tree");
        if (entries != null && entries.size() != 0) {
            List<PermissionNode> rootNodes = new ArrayList<>();
            entries.forEach((key, value) -> {
                rootNodes.add(JSONUtil.toBean((String) value, PermissionNode.class));
            });
            return rootNodes;
        }
        return null;
    }


    public void savePermissionTreeToRedis(List<PermissionNode> rootNodes) {
        Map<String, String> stringHashMap = new HashMap<>();
        for (PermissionNode permissionNode : rootNodes) {
            stringHashMap.put(String.valueOf(permissionNode.getId()), JSONUtil.toJsonStr(permissionNode));
        }
        stringRedisTemplate.opsForHash().putAll("permission:tree", stringHashMap);
    }
}





